package com.wenjie.original.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.Sets;
import com.mybatisflex.core.query.QueryWrapper;
import com.wenjie.common.utils.TokenUtil;
import com.wenjie.gateway.enums.ClentType;
import com.wenjie.original.entity.SysAdmin;
import com.wenjie.original.entity.SysAdminRole;
import com.wenjie.original.entity.SysMenu;
import com.wenjie.original.entity.SysRoleMenu;
import com.wenjie.original.entity.table.SysAdminRoleTableDef;
import com.wenjie.original.entity.table.SysRoleMenuTableDef;
import com.wenjie.original.entity.vo.SysMenu.MoveVo;
import com.wenjie.original.flex_config.baseInterface.Cus_ServiceImp;
import com.wenjie.original.mapper.SysMenuMapper;
import com.wenjie.original.service.ISysAdminRoleService;
import com.wenjie.original.service.ISysAdminService;
import com.wenjie.original.service.ISysMenuService;
import com.wenjie.original.service.ISysRoleMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.wenjie.original.entity.table.SysMenuTableDef.SYS_MENU;

/**
 * 菜单 业务层处理
 *
 * @author wenjie
 */
@Service
public class SysMenuServiceImpl extends Cus_ServiceImp<SysMenuMapper, SysMenu> implements ISysMenuService {

    // 根菜单的id
    public static final Long Arg0 = 0L;

    @Autowired
    private ISysAdminService adminService;

    @Autowired
    private ISysAdminRoleService adminRoleService;

    @Autowired
    private ISysRoleMenuService roleMenuService;

    @Autowired
    private ISysMenuService sysMenuService;


    /**
     * @Description 将菜单数据转换为树形结构
     * @author wenjie
     * @date 2024/6/17 10:18
     */
    @Override
    public List<Menu> treeStructure(List<SysMenu> sysMenus) {

        Map<Long, SysMenu> map = new HashMap<>(); // 将list转换为map
        List<Menu> topMenu = new ArrayList<>(); // 找到最上层的数据
        for (SysMenu sysMenu : sysMenus) {
            if (sysMenu.getParentId().equals(Arg0)) {
                topMenu.add(BeanUtil.toBean(sysMenu, Menu.class));
                continue;
            }
            map.put(sysMenu.getSysMenuId(), sysMenu);
        }

        for (Menu menu : topMenu) {
            getMenu(menu, map);
        }
        sortMenu(topMenu);
        return topMenu;
    }

    /**
     * @Description 将菜单栏数据进行一个筛选，筛选出 菜单类型的数据
     * @author wenjie
     * @date 2024/6/17 10:22
     */
    @Override
    public List<SysMenu> filterC(List<SysMenu> sysMenus) {
        List<SysMenu> restList = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            if (SysMenu.MENU_TYPE.argC.getCode().equals(sysMenu.getMenuType().getCode())) restList.add(sysMenu);
        }
        return restList;
    }

    @Override
    @Transactional
    public void delById(Long id) {
        SysMenu sysMenu = this.getById(id);
        Set<Long> ids = Sets.newHashSet(sysMenu.getSysMenuId());
        ids.addAll(slectChind(ids, this.list()));
        this.removeByIds(ids);
    }

    @Override
    public List<SysMenu> screenPermission() {
        TokenUtil.TokenInfo tokenInfo = TokenUtil.getTokenInfo();
        ClentType type = tokenInfo.getType();

        // 如果是最高用户权限的话  --- 最高权限用户的id为 1 有且仅有一个
        if (tokenInfo.getId() == 1L) {
            return sysMenuService.list();
        }

        // 如果是后台的话
        if (type.getCode().equals(ClentType.BACK_END.getCode())) {
            // 数据的处理
            SysAdmin admin = adminService.getById(tokenInfo.getId());

            // 查询用户的角色
            List<SysAdminRole> adminRoles = adminRoleService.list(QueryWrapper.create().where(SysAdminRoleTableDef.SYS_ADMIN_ROLE.SYS_ADMIN_ID.eq(tokenInfo.getId())));
            Set<Long> roleIds = adminRoles.stream().map(s -> s.getSysRoleId()).collect(Collectors.toSet());

            // 查询角色上面全部满足菜单
            List<SysRoleMenu> sysRoleMenus = roleMenuService.list(QueryWrapper.create().where(SysRoleMenuTableDef.SYS_ROLE_MENU.SYS_ROLE_ID.in(roleIds)));
            Set<Long> sysRoleMenuIds = sysRoleMenus.stream().map(s -> s.getSysMenuId()).collect(Collectors.toSet());

            // 查询符合的菜单信息
            return sysMenuService.list(QueryWrapper.create().where(SYS_MENU.SYS_MENU_ID.in(sysRoleMenuIds)));

        }

        return null;
    }

    @Override
    @Transactional
    public void move(MoveVo moveVo) {
        SysMenu change1 = this.getById(moveVo.getChange1());
        SysMenu change2 = this.getById(moveVo.getChange2());

        Long order1 = change1.getMenuOrder();
        Long order2 = change2.getMenuOrder();

        change1.setMenuOrder(order2);
        change2.setMenuOrder(order1);
        this.updateById(change1);
        this.updateById(change2);
    }

    public Set<Long> slectChind(Set<Long> parents, List<SysMenu> list) {
        HashSet<Long> set = new HashSet<>();
        for (SysMenu sysMenu : list) {
            if (parents.contains(sysMenu.getParentId())) set.add(sysMenu.getSysMenuId());
        }
        if (set.size() != 0) set.addAll(slectChind(set, list));

        return set;
    }


    /**
     * @Description 在map中查找menu的值
     * @author wenjie
     * @date 2024/6/15 17:41
     */
    private void getMenu(Menu menu, Map<Long, SysMenu> map) {
        if (map.size() <= 0) return;
        if (!SysMenu.MENU_TYPE.argM.getCode().equals(menu.getMenuType().getCode())) return;

        for (Long aLong : map.keySet()) {
            SysMenu sysMenu = map.get(aLong);
            if (sysMenu == null) continue;

            if (menu.getSysMenuId().equals(sysMenu.getParentId())) {
                map.put(aLong, null);

                if (menu.getMenuss() == null) menu.setMenuss(new ArrayList<>());

                Menu menuItem = BeanUtil.toBean(sysMenu, Menu.class);
                menu.getMenuss().add(menuItem);
                getMenu(menuItem, map);
            }
        }
    }

    /**
     * @Description 对菜单进行排序
     * @author wenjie
     * @date 2024/6/15 17:53
     */
    private void sortMenu(List<Menu> menus) {
        sortMenuCollection(menus);

        for (Menu menu : menus) {
            sortMenu(menu);
        }
    }


    /**
     * @Description 对菜单进行排序
     * @author wenjie
     * @date 2024/6/15 17:53
     */
    private void sortMenu(Menu menu) {
        List<Menu> menuss = menu.getMenuss();
        if (menuss == null || menuss.size() == 0) return;
        sortMenuCollection(menuss);
        // 对这个集合进行排序
        for (Menu item : menuss)
            sortMenu(item);

    }


    /**
     * @Description 对菜单进行排序
     * @author wenjie
     * @date 2024/6/15 17:53
     */
    private void sortMenuCollection(List<Menu> menus) {
        Collections.sort(menus, new Comparator<Menu>() {
            @Override
            public int compare(Menu stu1, Menu stu2) {
                Long res = stu1.getMenuOrder() - stu2.getMenuOrder();
                if (res == 0L) return 0;
                if (res > 0L) return 1;
                return -1;
            }
        });
    }


    /**
     * @Description 对菜单进行排序
     * @author wenjie
     * @date 2024/6/15 17:53
     */
    private void sortSysMenu(List<SysMenu> menus) {
        Collections.sort(menus, new Comparator<SysMenu>() {
            @Override
            public int compare(SysMenu stu1, SysMenu stu2) {
                Long res = stu1.getMenuOrder() - stu2.getMenuOrder();
                if (res == 0L) return 0;
                if (res > 0L) return 1;
                return -1;
            }
        });
    }


}
